#include "myFILE.h"
#include <stdio.h>

FILE_ *fopen_(const char *path_name, const char *mode)
{
    int flags = 0;             // 文件打开方式
    mode_t defaultMode = 0666; // 默认权限
    if (strcmp(mode, "r") == 0)
    {
        flags |= O_RDONLY;
    }
    else if (strcmp(mode, "w") == 0)
    {
        flags |= (O_WRONLY | O_CREAT | O_TRUNC);
    }
    else if (strcmp(mode, "a") == 0)
    {
        flags |= (O_APPEND | O_CREAT | O_WRONLY);
    }
    else
    {
        // ...
    }
    mode_t oldMask = umask(0); // 获取当前umask值
    int fd = open(path_name, flags, defaultMode);
    umask(oldMask); // 恢复之前的umask值
    if (fd < 0)
    {
        const char *errMsg = strerror(errno);
        write(2, errMsg, strlen(errMsg)); // 将错误内容写到stderr
        return NULL;
    }
    FILE_ *fp = (FILE_ *)malloc(sizeof(FILE_));
    assert(fp);
    fp->flags = SYNC_LINE; // 默认设置为行刷新
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->size = 0;
    memset(fp->buffer, 0, SIZE);
    return fp; // 打开文件返回FILE*的指针
}

void fwrite_(const void *ptr, int num, FILE_ *fp) // 把数据写到缓冲区
{
    memcpy(fp->buffer + fp->size, ptr, num); // 先写到缓冲区，不考虑缓冲区满的情况
    fp->size += num;
    // 判断是否刷新
    if (fp->flags & SYNC_NOW)
    {
        write(fp->fileno, fp->buffer, fp->size);
        fp->size = 0; // 清空缓冲区
    }
    else if (fp->flags & SYNC_FULL)
    {
        if (fp->size == fp->cap)// 缓冲区满后写到文件
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0;
        }
    }
    else if (fp->flags & SYNC_LINE)
    {
        if (fp->buffer[fp->size - 1] == '\n')// 碰到\n直接写到文件
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0;
        }
    }
}
void fflush_(FILE_ *fp)
{
    if (fp->size > 0)
    {
        write(fp->fileno, fp->buffer, fp->size);
        fsync(fp->fileno); // 将数据强制刷新至磁盘
    }
}
void fclose_(FILE_ *fp) // 关闭文件
{
    fflush_(fp); // 刷新文件
    close(fp->fileno);
}